local uu       = require('modules.commhm.utils')
local mis_config   = require('mis_config');
local mis_rank     = require('mis_rank')

local log       = require("modules.commhm.log");
local mis_data     = nil
local mis_log      = nil
local mis_bridge   = nil
local t_retCode    = nil


local ngx = ngx
local pairs = pairs
local table = table
local math = math
local math_max = math.max
local math_min = math.min
local tonumber = tonumber
local tostring = tostring
local table_insert = table.insert


local MAP_ID = "84134114362578"

-- 斗罗大陆
local this = {
	s_name = string.match(debug.getinfo(1).short_src, '.*/(.*).lua');	-- 模块名称
}


this.log = function (...)
    local t = {...}
    local msg = table.concat(t, "|")
	mis_log.day(this.s_name, msg)
end


--斗罗大陆数据打点
this.report_log = function (action, tab)
    local name = "douluodalu" .. "_" .. action
    local t_params = ngx.ctx.t_params
    local t_ = {
        ip = t_params.s_remoteAddr or ngx.ctx.xff or ngx.var.remote_addr or "nil";
		uin = t_params.uin;
		time = uu.now();
		country = t_params.country or 'nil';
		apiid = t_params.apiid or 'nil';
		ver = t_params.ver or 'nil';
		lang = t_params.lang or 'nil';
    }
    for k, v in pairs(tab) do
        t_[k] = v
    end
    mis_log.remote_pure_day(name, uu.table2json(t_))
end


local add_items = function(n_uin, userdata, t_items, s_type, reason)
    local t_normal, t_special = {}, {}
	for _, t_ in pairs(t_items) do
		if mis_config.t_specialItemMap[t_.id] then
			t_special[t_.id] = t_special[t_.id] and t_special[t_.id] + t_.num or t_.num
		else
			t_normal[#t_normal+1] = t_
		end
	end
	if next(t_special) then
		for id, num in pairs(t_special) do
            userdata.exchange_num = (userdata.exchange_num or 0) + num
        end
	end
	if #t_normal > 0 then
		return mis_bridge.add_items(n_uin, t_normal, s_type, reason)
	end
	return t_retCode.n_OK
end


local get_today_zero_time = function(time)
    time = time or os.time()
    local now_date = os.date("*t", time)
    local today_time = os.time{year=now_date.year, month=now_date.month, day=now_date.day, hour=0,min=0,sec=0}
    return today_time
end


local is_same_day = function(time1, time2)
    local day1 = get_today_zero_time(time1)
    local day2 = get_today_zero_time(time2)
    return day1 == day2
end


--刷新奖励状态
local flush_rewards_data = function (userdata, s_type)
    local ret = this.update_cloud_server_room(userdata, s_type)
    userdata.rewards_data = userdata.rewards_data or {}
    local last_time = userdata.rewards_data.last_flush_time or 0
    if is_same_day(last_time, uu.now()) then
        return ret
    end
    userdata.rewards_data.last_flush_time = uu.now()
    local daily_map = {[1] = true, [4] = true}
    userdata.rewards_data.data = userdata.rewards_data.data or {}
    for i = 1, 5 do
        userdata.rewards_data.data[i] = userdata.rewards_data.data[i] or 0
        if daily_map[i] then
            userdata.rewards_data.data[i] = 0
        end
    end
    userdata.daily_max_limit = 0

	local t_Config = mis_data.t_share_mission[s_type] or {}
	-- 榜单配置
    for s_mapID, t_rankConf in  pairs(t_Config.t_conf.t_rank or {}) do
        if t_rankConf.daily == 1 then
            userdata.map = userdata.map or {}
            userdata.map[s_mapID] = nil
        end
    end

    return true
end


--上报vip数据
this.update_cloud_server_room = function (userdata, s_type)
    local t_Config = mis_data.t_share_mission[s_type] or {}
    if not (t_Config and t_Config.t_conf and t_Config.t_conf.stage) then
        return
    end

    local ret, is_vip = mis_bridge.query_mini_vip(ngx.ctx.t_params.uin)
    if not ret then
        this.log("pick_rewards", "query vip error", ngx.ctx.t_params.uin, s_type)
    end
    if 1 then -- 改成每次请求都写，云服会清理会员数据
    --if userdata.is_vip ~= is_vip then  
        local val_ = is_vip and "1" or "0"
        local mapID = t_Config.t_conf.query_data_mapid
        local namespace = 'DouluoVIP:global'
        local key = ngx.ctx.t_params.uin
        if not mis_bridge.set_cloud_dhs_data(mapID, namespace, key, val_) then
            this.log( 'douluodalu cloud dhs updata fault', uu.to_str({
                namespace = namespace,
                mapID = mapID,
                key   = ngx.ctx.t_params.uin,
                value = val_,
            }))
            return
        end
        userdata.is_vip = true
	    return true, is_vip
    end
end


local REWARDS_MAP = {
    [1] = "login_rewards",
    [2] = "bind_phone",
    [3] = "team_rewards",
    [4] = "vip_rewards",
    [5] = "ready_rewards",
}


local check_rewards = {
    [1] = function ()
        return true
    end,
    [2] = function ()
        return mis_bridge.query_bind_phone(ngx.ctx.t_params.uin)
    end,
    [3] = function (s_type, userdata)
        if not userdata.captain_uin then
            return false
        end
        local n_code, captain_userdata
        if userdata.captain_uin == ngx.ctx.t_params.uin then
            captain_userdata = userdata
        else
            local t_captainUser = mis_data.get_user(userdata.captain_uin)
            n_code, captain_userdata = t_captainUser:get_share_mission_data(s_type, 1)
            if n_code ~= t_retCode.n_OK then
                this.log("pick_rewards","get captain data error", userdata.captain_uin, ngx.ctx.t_params.uin, s_type)
                return false
            end
        end
        if #captain_userdata.team ~= 7 then
            return false
        end
        return true
    end,
    [4] = function (s_type)
        local ret, is_vip = mis_bridge.query_mini_vip(ngx.ctx.t_params.uin)
        if not ret then
            this.log("pick_rewards","query vip error", ngx.ctx.t_params.uin, s_type)
        end
        return is_vip
    end,
    [5] = function (s_type, userdata)
        if  not userdata.is_booking then
            return false
        end
        return true
    end
}


local get_client_data = function (userdata, s_type)
    local n_code, captain_userdata
    if userdata.captain_uin then
        if userdata.captain_uin == ngx.ctx.t_params.uin then
            captain_userdata = userdata
        else
            local t_captainUser = mis_data.get_user(userdata.captain_uin)
            n_code, captain_userdata = t_captainUser:get_share_mission_data(s_type, 1)
            if n_code ~= t_retCode.n_OK then
                this.day("pick_rewards","get captain data error", userdata.captain_uin, ngx.ctx.t_params.uin, s_type)
                return false
            end
        end
    end
    userdata.rewards_data = userdata.rewards_data or {}
    return {
        rewards_status = userdata.rewards_data.data,
        captain_uin = userdata.captain_uin,
        team = captain_userdata and captain_userdata.team,
        badge_info = userdata.badge_info or {level = 1, score = 0},
        daily_max_limit = userdata.daily_max_limit or 0,
        level_info = userdata.level_info or {level=10, huan_map={0,0,0,0,0,0,0,0,0,0}},
        exchange_num = userdata.exchange_num or 0,
        is_booking = userdata.is_booking and 1 or 0,
    }
end


this.douluodalu_pick_rewards = function ()
	local n_code, t_user, t_userData, ts_desc,s_items
    local t_params = ngx.ctx.t_params
    local s_type = t_params.mission_type
    local pick_type = tonumber(t_params.pick_type)
    if not (pick_type and s_type and REWARDS_MAP[pick_type]) then
        return t_retCode.n_PARAM_ERR, 's_type error'
    end
    local t_Config = mis_data.t_share_mission[s_type] or {}

    local cfg = t_Config.t_conf and t_Config.t_conf[REWARDS_MAP[pick_type]]
    if not (cfg) then
		return t_retCode.n_PARAM_ERR, 'config error'
	end

    local now = uu.now()
    if now < cfg.n_startTime or now > cfg.n_endTime then
        return t_retCode.n_OPER_ERR, "limit time"
    end
    t_user = mis_data.get_user()
	n_code, t_userData = t_user:get_share_mission_data(s_type)
	if n_code ~= t_retCode.n_OK then
		return n_code, 'get user data error'
	end

    t_userData.rewards_data = t_userData.rewards_data or {}

    t_userData.rewards_data.data = t_userData.rewards_data.data or {}
    --检查是否已领取
    if t_userData.rewards_data.data[pick_type] ~= 0 then
        return t_retCode.n_OPER_ERR, "had pick, pick_type : " .. pick_type
    end

    -- 条件检查
    if not check_rewards[pick_type](s_type, t_userData) then
        return t_retCode.n_OPER_ERR, "check fail, pick_type : " .. pick_type
    end

    -- 发奖
    n_code, ts_desc, s_items = add_items(t_params.uin, t_userData, cfg.rewards,s_type, 'mis_douluodalu')
	if n_code ~= t_retCode.n_OK then
		return n_code, ts_desc
	end
    t_userData.rewards_data.data[pick_type] = 1
    local n_code, s_desc = t_user:set_share_mission_data(s_type, t_userData)
	if n_code ~= t_retCode.n_OK then
		return n_code, s_desc
	end

    --数据打点
    this.report_log("pick_rewards", {
        pick_action = REWARDS_MAP[pick_type],
        pick_type = pick_type,
        items = cfg.rewards,
    })

    local ret = get_client_data(t_userData, s_type)
    return t_retCode.n_OK, ret
end


local query_douluodalu_data = function(s_type)
    local t_Config = mis_data.t_share_mission[s_type] or {}
    if not (t_Config and t_Config.t_conf and t_Config.t_conf.stage) then
        return false, {error = 1}
    end
    local id = t_Config.t_conf.query_data_mapid
    local namespace = "Biao"
    local key = ngx.ctx.t_params.uin
    local  ret, rst = mis_bridge.get_cloud_dhs_data(id, namespace, key)
    if not ret then
        this.log("query douluodalu cloud error", id, key)
        return false, {error = 2}
    end
    local a, b = string.find(rst, "&")
    if not a or not b then
        return false, {error = 3, str = rst}
    end
    local json_str = string.sub(rst, b+1)
    local map_info = uu.json2table(json_str)
    if not map_info then
        return false, {error = 4}
    end
    local huan_info = (map_info.Huan or {}).HuanWei or {}
    if #huan_info ~= 10 then
        return false, {error = 5}
    end
    local huan_map = {}
    for i=1, #huan_info do
        huan_map[#huan_map+1] = huan_info[i].equipedRank
    end
    return true, {
        level = map_info.lvlCur,  --等级
        huan_map = huan_map
    }
end


-- 小队集结
this.douluodalu_join_team = function()
	local t_params 			= ngx.ctx.t_params
	local n_inviteUin		= tonumber(t_params.invite_uin)
	local s_type			= t_params.mission_type
	local n_code, s_desc
	local t_user, t_userData
	local t_inviteUser, t_inviterData
	local t_captainUser, t_captainData
	local t_memberUser, t_memberData
    local t_taskConf		= mis_data.t_share_mission[s_type].t_conf
    local role_module = t_params.role_module
    local role_name = t_params.role_name

	t_user = mis_data.get_user()
	n_code, t_userData = t_user:get_share_mission_data(s_type)
	if n_code ~= t_retCode.n_OK then
		return n_code, 'get user data error'
	end

	-- 不能邀请自己
	if n_inviteUin == t_params.uin then
        this.log("join_team_error", "can't join self team", t_params.uin, n_inviteUin, s_type)
		return t_retCode.n_OPER_ERR, "can't join self team"
	end

	-- 判断是否已经加入队伍
	if t_userData.captain_uin ~= nil then
        this.log("join_team_error", "already join", t_params.uin, n_inviteUin, t_userData.captain_uin, s_type)
		return t_retCode.n_CONVOY_ALREADY_JOIN, "already join team"
	end

	-- 找到队长
	t_inviteUser = mis_data.get_user(n_inviteUin)
	n_code, t_inviterData = t_inviteUser:get_share_mission_data(s_type)
	if n_code ~= t_retCode.n_OK then
        this.log("join_team_error","get inviter data error", t_params.uin, n_inviteUin, s_type)
		return n_code, 'get inviter data error'
	end

	if t_inviterData.captain_uin == n_inviteUin then
		t_captainUser = t_inviteUser
		t_captainData = t_inviterData
	elseif t_inviterData.captain_uin ~= nil then
		t_captainUser = mis_data.get_user(t_inviterData.captain_uin)
		n_code, t_captainData = t_captainUser:get_share_mission_data(s_type)
		if n_code ~= t_retCode.n_OK then
			this.log("join_team_error","get captain data error", t_params.uin, n_inviteUin, s_type)
			return n_code, 'get captain data error'
		end
	else
		-- 新建队伍
		t_inviterData.team = {}
		t_inviterData.captain_uin = n_inviteUin

        this.log("join_team","new team", t_params.uin, n_inviteUin, s_type)

		t_captainUser = t_inviteUser
		t_captainData = t_inviterData
	end

	if t_captainData.team == nil then
        this.log("join_team_error", "team not set up", t_params.uin, n_inviteUin, t_captainUser.n_uin, s_type)
		return t_retCode.n_WORK_ERR, "team not set up"
	end

	-- 判断队伍是否已满
	if #t_captainData.team >= 7 then
        this.log("join_team_error","team is full", t_params.uin, n_inviteUin, uu.to_str(t_captainData.captain_uin), s_type, uu.to_str(t_captainData.team))
		return t_retCode.n_CONVOY_IS_FULL, "team is full"
	end
    t_captainData.level_info = t_captainData.level_info or {
        uin=t_inviterData.captain_uin, 
        role_module=t_captainData.role_module,
        level=10,
        role_name=t_captainData.role_name,
        huan_map={0,0,0,0,0,0,0,0,0,0},
    }
    t_userData.level_info = t_userData.level_info or {
        uin=t_params.uin,
        role_module=t_userData.role_module or role_module,
        level=10,
        role_name=t_userData.role_name,
        huan_map={0,0,0,0,0,0,0,0,0,0},
    }
	-- 如果是新建的队伍
	if #t_captainData.team == 0 then
		t_captainData.team[1] = t_captainData.level_info
		t_captainData.team[2] = t_userData.level_info
		t_userData.captain_uin = t_captainUser.n_uin
	else
		-- 加入已有队伍
		t_captainData.team[#t_captainData.team + 1] = t_userData.level_info
		t_userData.captain_uin = t_captainUser.n_uin
	end

    -- 保存队长数据
    n_code, s_desc = t_captainUser:set_share_mission_data(s_type, t_captainData)
    if n_code ~= t_retCode.n_OK then
        this.log("join_team_error","join_team save error", t_params.uin, uu.to_str(n_code), s_type, s_desc, t_memberUser.n_uin)
    end

    -- 保存自己数据
    n_code, s_desc = t_user:set_share_mission_data(s_type, t_userData)
    if n_code ~= t_retCode.n_OK then
        this.log("join_team_error","join_team save error", t_params.uin, uu.to_str(n_code), s_type, s_desc, t_memberUser.n_uin)
    end

	this.log("join_team", "ok", uu.to_str(t_captainData.team))

	return t_retCode.n_OK, {team = t_captainData.team}
end

-- 比较魂环
local compare_huan = function (level_info, t_level_info)
    level_info = level_info or {}
    t_level_info = t_level_info or {}
    level_info.huan_map = level_info.huan_map or {}
    t_level_info.huan_map = t_level_info.huan_map or {}

    for i=1, 10 do
        if level_info.huan_map[i] ~= t_level_info.huan_map[i] then
            return true
        end
    end
end


-- 更新个人数据
local updata_role_data = function(t_userData, s_type)
    local t_params = ngx.ctx.t_params
    local ret, level_info = query_douluodalu_data(s_type)
    if not ret then
        this.log("updata team data error " .. "|" ..ngx.ctx.t_params.uin)
        return
    end
    local n_code, s_desc
    t_userData.level_info = t_userData.level_info or {}
    if t_userData.level_info.role_name  ~= t_userData.role_name 
        or t_userData.level_info.role_module  ~= t_userData.role_module 
        or level_info.level~=t_userData.level_info.level
        or compare_huan(level_info, t_userData.level_info) then
        t_userData.level_info = level_info
        t_userData.level_info.role_module = t_userData.role_module
        t_userData.level_info.role_name = t_userData.role_name
        t_userData.level_info.uin = ngx.ctx.t_params.uin
        return true
    end
end


-- 更新队伍数据 -- 只保存队长数据，自己数据返回后处理
local update_team_data = function(t_userData, s_type)
    local t_params = ngx.ctx.t_params
    local n_code, captain_userdata, t_captainUser,s_desc
    if t_userData.captain_uin == ngx.ctx.t_params.uin then
        captain_userdata = t_userData
    else
        t_captainUser = mis_data.get_user(t_userData.captain_uin)
        n_code, captain_userdata = t_captainUser:get_share_mission_data(s_type)
        if n_code ~= t_retCode.n_OK then
            this.log("pick_rewards","get captain data error", t_userData.captain_uin, ngx.ctx.t_params.uin, s_type)
            return false
        end
    end
    local ret, level_info = query_douluodalu_data(s_type)
    if not ret or uu.tableIsEmpty(level_info) then
        this.log("updata team data error ", ngx.ctx.t_params.uin,  uu.to_str({
            ret=ret,level_info=level_info,
        }))
        level_info = t_userData.level_info or {}
    end
    t_userData.level_info = t_userData.level_info or {}
    if t_userData.level_info.role_name  ~= t_userData.role_name 
            or t_userData.level_info.role_module  ~= t_userData.role_module 
            or level_info.level~=t_userData.level_info.level
            or compare_huan(level_info, t_userData.level_info) then
        t_userData.level_info = level_info
        t_userData.level_info.role_module = t_userData.role_module
        t_userData.level_info.role_name = t_userData.role_name
        t_userData.level_info.uin = ngx.ctx.t_params.uin
        local key = 0
        for k, v in pairs(captain_userdata.team) do
            if ngx.ctx.t_params.uin == v.uin then
                key = k
                break
            end
        end
        captain_userdata.team[key] = t_userData.level_info
        if t_userData.captain_uin ~= ngx.ctx.t_params.uin then
            -- 保存队长数据
            n_code, s_desc = t_captainUser:set_share_mission_data(s_type, captain_userdata)
            if n_code ~= t_retCode.n_OK then
                this.log("join_team_error","join_team save error", t_params.uin, uu.to_str(n_code), s_type, s_desc )
            end
        end
        return true
    end
end


-- 结束地图 上报更新数据
this.douluodalu_finish_map = function ()
    local t_params = ngx.ctx.t_params
    local s_type = t_params.mission_type

    local t_user, n_code, t_userData, updata
    t_user = mis_data.get_user()
	n_code, t_userData = t_user:get_share_mission_data(s_type)
	if n_code ~= t_retCode.n_OK then
		return n_code, 'get user data error'
	end
    if t_userData.captain_uin then
        updata = update_team_data(t_userData, s_type)
    else
        updata = updata_role_data(t_userData, s_type)
    end
    if updata then
        local n_code, s_desc = t_user:set_share_mission_data(s_type, t_userData)
        if n_code ~= t_retCode.n_OK then
            return n_code, s_desc
        end
    end
    return t_retCode.n_OK, get_client_data(t_userData, s_type)
end


-- 结束地图 上报更新数据
this.douluodalu_clear_data = function ()
    local t_params = ngx.ctx.t_params
    local s_type = t_params.mission_type

    local t_user, n_code, t_userData, updata
    t_user = mis_data.get_user()
	n_code, t_userData = t_user:get_share_mission_data(s_type)
	if n_code ~= t_retCode.n_OK then
		return n_code, 'get user data error'
	end
    t_userData = {}
    local n_code, s_desc = t_user:set_share_mission_data(s_type, t_userData)
    if n_code ~= t_retCode.n_OK then
        return n_code, s_desc
    end
    
    return t_retCode.n_OK, get_client_data(t_userData, s_type)
end


-- 上报斗魂场积分
this.douluodalu_update_score = function()
    local t_params = ngx.ctx.t_params
    local s_type = t_params.mission_type
    local victory = tonumber(t_params.victory)

    if victory ~= 1 and victory ~= 2 then
        return t_retCode.n_PARAM_ERR, "victory err"
    end
    if not s_type then
        return t_retCode.n_PARAM_ERR, 's_type error '
    end

    local t_user, n_code, t_userData
    t_user = mis_data.get_user()
	n_code, t_userData = t_user:get_share_mission_data(s_type)
	if n_code ~= t_retCode.n_OK then
		return n_code, 'get user data error'
	end
    local now = uu.now()
    t_userData.last_rank_report = t_userData.last_rank_report or 0
    if t_userData.last_rank_report + 600 > now then
        return t_retCode.n_PARAM_ERR, 's_type error '
    end
    t_userData.last_rank_report = now
    -- 刷新数据
    flush_rewards_data(t_userData, s_type)

    t_userData.badge_info = t_userData.badge_info or {
        level = 1,
        score = 0,
    }
    local t_Config = mis_data.t_share_mission[s_type] or {}
    local cfg = t_Config.t_conf and t_Config.t_conf.badge_level
    if not (cfg) then
		return t_retCode.n_PARAM_ERR, 'config error'
	end

    local level_info = cfg[t_userData.badge_info.level]
    t_userData.badge_info.score = t_userData.badge_info.score + (level_info.score_rewards[victory].score or 0)
    if t_userData.badge_info.score < 0 then --不降级
        t_userData.badge_info.score = 0
    end
    if t_userData.badge_info.score > level_info.score_max then
        if not cfg[t_userData.badge_info.level + 1] then --最高徽章，在无法升级
            if t_userData.badge_info.score > 99999 then
                t_userData.badge_info.score = 99999
            end
            -- t_userData.badge_info.score = level_info.score_max --积分可以无限加
        else
            t_userData.badge_info.level = t_userData.badge_info.level + 1 --升级
            t_userData.badge_info.score = t_userData.badge_info.score - level_info.score_max
        end
    end
    --发奖
    if (t_userData.daily_max_limit or 0) < t_Config.t_conf.daily_max_limit then
        local rewards = {}
        local items = level_info.score_rewards[victory].items
        for _, item in pairs(items) do
            if item.id == 'mis_item_3' then
                local num = item.num
                if (t_userData.daily_max_limit or 0) + item.num > t_Config.t_conf.daily_max_limit then
                    num = t_Config.t_conf.daily_max_limit - (t_userData.daily_max_limit or 0)
                end
                t_userData.daily_max_limit = (t_userData.daily_max_limit or 0) + num
                table.insert(rewards, {id=item.id, num=num})
            else
                table.insert(rewards, item)
            end
        end

        local items = level_info.score_rewards[victory].items
        local n_code, ts_desc, s_items = add_items(t_params.uin,t_userData, rewards, s_type, 'mis_douluodalu')
        if n_code ~= t_retCode.n_OK then
            return n_code, ts_desc
        end
    end
    this.deal_rank(t_userData, s_type, victory==1, t_userData.badge_info)
    local n_code, s_desc = t_user:set_share_mission_data(s_type, t_userData)
	if n_code ~= t_retCode.n_OK then
		return n_code, s_desc
	end
    return t_retCode.n_OK, get_client_data(t_userData, s_type)
end


this.douluodalu_client_info = function()
    local t_params = ngx.ctx.t_params
    local s_type = t_params.mission_type
    local role_module = t_params.role_module
    local role_name = t_params.role_name
    if not s_type then
		return t_retCode.n_PARAM_ERR, 's_type error'
	end

    local t_user, n_code, t_userData, update,s_desc
    t_user = mis_data.get_user()
	n_code, t_userData = t_user:get_share_mission_data(s_type)
	if n_code ~= t_retCode.n_OK then
		return n_code, 'get user data error'
	end
    local is_flush = flush_rewards_data(t_userData, s_type)

    local ret = get_client_data(t_userData, s_type)
    t_userData.role_module = role_module
    t_userData.role_name = role_name
    if t_userData.captain_uin then
        update = update_team_data(t_userData, s_type)
    else
        update = updata_role_data(t_userData, s_type)
    end

    if is_flush or update then
        n_code, s_desc = t_user:set_share_mission_data(s_type, t_userData)
        if n_code ~= t_retCode.n_OK then
            this.log("join_team_error","join_team save error", t_params.uin, uu.to_str(n_code), s_type, s_desc)
        end
    end
    return t_retCode.n_OK, ret
end


this.douluodalu_booking = function ()
    local t_params = ngx.ctx.t_params
    local s_type = t_params.mission_type
    local t_user, n_code, t_userData, update,s_desc

    t_user = mis_data.get_user()
    n_code, t_userData = t_user:get_share_mission_data(s_type)
	if n_code ~= t_retCode.n_OK then
		return n_code, 'get user data error'
	end
    t_userData.is_booking = true
    n_code, s_desc = t_user:set_share_mission_data(s_type, t_userData)
    if n_code ~= t_retCode.n_OK then
        this.log("booking err", t_params.uin, uu.to_str(n_code), s_type, uu.to_str(s_desc))
    end
    local ret = get_client_data(t_userData, s_type)
    return t_retCode.n_OK, ret
end


local get_map_ranking = function (s_mapID)
	return mis_rank.instance('douluo_' .. s_mapID)
end


this.get_rank_top = function ()
	local t_params = ngx.ctx.t_params
	local n_uin    = t_params.uin
	local s_mapID  = tonumber(t_params.mapId)
	local version  = t_params.rank_ver
	local n_page   = tonumber(t_params.page) or 1
	local s_type = "douluodalu"

	local ranking = get_map_ranking(s_mapID)
	if not ranking then
		return t_retCode.n_WORK_ERR, 'rank instance not found'
	end

	-- 角色自身缓存数据
	local t_user = mis_data.get_user()
	local n_code, t_userData = t_user:get_share_mission_data(s_type, true)
	if n_code ~= t_retCode.n_OK then
		return n_code, 'get user data error'
	end

	t_userData.map = t_userData.map or {}
	t_userData.map[s_mapID] = t_userData.map[s_mapID] or {}

	-- 组装消息数据
	local t_rankTop = ranking:Get() or {}
	local n_pageCnt = version and version ~= t_rankTop.version and 1 or n_page
	local rsp = {
		rank    = {},                 -- 一页榜单数据
		page    = n_pageCnt,		  -- 当前是第几页
		total   = t_rankTop.total,    -- 可展示榜单数
		version = t_rankTop.version,  -- 榜单版本信息
		self    = {                   -- 自己的排名信息
			rank  = -1,             -- 不在前100名榜单内
			value = t_userData.map[s_mapID].rankValue or 0
		}
	}
	-- 每页返回20个玩家数据
	local start = (n_pageCnt - 1) * 100 + 1
	local final =  n_pageCnt * 100
	for top, role in pairs(t_rankTop.rank or {}) do
		if top >= start and top <= final then
			rsp.rank[top] = role
		end
		if tonumber(role.uid) == n_uin then
			rsp.self.rank  = top
			rsp.self.value = role.value
		end
	end

	return t_retCode.n_OK, rsp
end


local update_role_map_value = function (t_userData,s_type, t_rankConf, s_mapID, n_value)
	-- 角色自身缓存数据
	t_userData.map = t_userData.map or {}
	t_userData.map[s_mapID] = t_userData.map[s_mapID] or {}
	-- TODO: 这块的逻辑应该挪入排汗榜模块内
	if t_rankConf.updates == mis_rank.Updates.FullVolume then
		if t_rankConf.order_by == mis_rank.OrderBy.ASC then
			t_userData.map[s_mapID].rankValue = n_value
		else
			t_userData.map[s_mapID].rankValue = n_value
		end
	else
		t_userData.map[s_mapID].rankValue = t_userData.map[s_mapID].rankValue or 0
		t_userData.map[s_mapID].rankValue = t_userData.map[s_mapID].rankValue + n_value
	end

	return t_retCode.n_OK
end


this.deal_rank = function(t_userData, s_type, victory, badge_info)
    local t_Config = mis_data.t_share_mission[s_type] or {}
    local ret, s_mapID
    if victory then
        s_mapID = 10000001
        ret = this.update_rank(t_userData, s_mapID, 1, s_type)
        if ret ~= t_retCode.n_OK then
            this.log("uin " .. ngx.ctx.t_params.uin  .. "|" .. uu.to_str({
                s_mapID = s_mapID,
                victory = victory,
                badge_info = badge_info
            }))
        end
    end
    s_mapID = 10000002
    local value =  badge_info.level * 100000 + badge_info.score
    ret = this.update_rank(t_userData, s_mapID, value, s_type)
    if ret ~= t_retCode.n_OK then
        this.log("uin " .. ngx.ctx.t_params.uin  .. "|" .. uu.to_str({
            s_mapID = s_mapID,
            victory = victory,
            badge_info = badge_info
        }))
    end
end

this.update_rank = function (t_userData, s_mapID, n_value, s_type)
	local t_params   = ngx.ctx.t_params
	local n_uin      = t_params.uin

	if not n_value then
		return t_retCode.n_PARAM_ERR
	end

	local t_Config = mis_data.t_share_mission[s_type] or {}
	-- 榜单配置
	local t_rankConf = t_Config.t_conf.t_rank[s_mapID] or {}
	if uu.tableIsEmpty(t_rankConf) then
		return t_retCode.n_OPER_ERR, 'no rank conf'
	end

	if t_rankConf.limit_min and n_value < t_rankConf.limit_min then
		return t_retCode.n_OPER_ERR, 'invalid value min'
	end
	if t_rankConf.limit_max and n_value > t_rankConf.limit_max then
		return t_retCode.n_OPER_ERR, 'invalid value min'
	end


	local n_code, s_desc = update_role_map_value(t_userData, s_type, t_rankConf, s_mapID, n_value)
	if n_code ~= t_retCode.n_OK then
		return n_code, s_desc
	end

	local t_profile = {
		rolename  = t_params.rolename,
		portrait  = t_params.portrait,
		headframe = t_params.headframe,
	}
	local ranking = get_map_ranking(s_mapID)
	if not ranking or not ranking:Set( n_uin, t_userData.map[s_mapID].rankValue, t_profile ) then
		return t_retCode.n_PARAM_ERR, "set rank err"
	end

	return t_retCode.n_OK
end


-- 说明：模块包含
-- 参数：模块表
this.modules_include = function(t_moddules)
	mis_data     = t_moddules.mis_data
	mis_log      = t_moddules.mis_log
	mis_bridge   = t_moddules.mis_bridge
	mis_config   = t_moddules.mis_config
	t_retCode    = mis_config.t_retCode
end


return this